﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BCCommon;
using BCCommon.Enums;
using BCData.WeChatComponent.WeChatMediaRecord;
using BCData.WeChatComponent.WeChatMessagePushRecord;
using BCData.WeChatComponent.WeChatNewsMaterialArticleRecord;
using BCDto.WeChatComponent.WeChatMediaRecord;
using BCDto.WeChatComponent.WeChatNewsMaterialArticleRecord;
using BCEntity.WeChatComponent.WeChatMediaRecord;
using BCEntity.WeChatComponent.WeChatNewsMaterialArticleRecord;
using BCService.Utils;
using BCService.Common.WebsiteConfigurationService;
using BCService.WeChatComponent.WeChatMaterialService.WeChatNewsMaterialService;
using Newtonsoft.Json;
using WeChatSDK.WeChatDto.Material;
using WeChatSDK.WeChatServiceComponent.Material;
using Microsoft.Extensions.Configuration;

namespace BCService.WeChatComponent.WeChatNewsMaterialArticleRecordService
{
    /// <summary>
    /// 微信图文素材文章记录服务
    /// </summary>
    public class WeChatNewsMaterialArticleRecordService : IWeChatNewsMaterialArticleRecordService
    {
        private readonly IConfiguration configuration;
        private readonly IWeChatMediaRecordData weChatMediaRecordData;
        private readonly IWeChatNewsMaterialArticleRecordData weChatNewsMaterialArticleRecordData;
        private readonly IWeChatMessagePushRecordData weChatMessagePushRecordData;
        private readonly IWeChatNewsMaterialService weChatNewsMaterialService;
        private readonly IWebsiteConfigurationService websiteConfigurationService;

        public WeChatNewsMaterialArticleRecordService(IConfiguration configuration,
            IWeChatMediaRecordData weChatMediaRecordData,
            IWeChatNewsMaterialArticleRecordData weChatNewsMaterialArticleRecordData,
            IWeChatMessagePushRecordData weChatMessagePushRecordData,
            IWeChatNewsMaterialService weChatNewsMaterialService,
            IWebsiteConfigurationService websiteConfigurationService)
        {
            this.configuration = configuration;
            this.weChatMediaRecordData = weChatMediaRecordData;
            this.weChatNewsMaterialArticleRecordData = weChatNewsMaterialArticleRecordData;
            this.weChatMessagePushRecordData = weChatMessagePushRecordData;
            this.weChatNewsMaterialService = weChatNewsMaterialService;
            this.websiteConfigurationService = websiteConfigurationService;
        }

        public WeChatMediaRecordDto Add(IEnumerable<WeChatNewsMaterialArticleRecordRequestDto> weChatNewsMaterialArticleRecordRequestDtos)
        {

            List<NewsArticles> articles = new List<NewsArticles>();
            List<WeChatNewsMaterialArticleRecordEntity> entities = new List<WeChatNewsMaterialArticleRecordEntity>();
            foreach (WeChatNewsMaterialArticleRecordRequestDto dto in weChatNewsMaterialArticleRecordRequestDtos)
            {
                entities.Add(dto.As<WeChatNewsMaterialArticleRecordEntity>());

                articles.Add(new NewsArticles()
                {
                    Author = dto.Author,
                    Content = dto.WeChatContent,//TODO:这里需要增加对素材的地址转换
                    ContentSourceUrl = dto.ContentSourceUrl,
                    Digest = dto.Digest,
                    ShowCoverPic = 1,
                    ThumbMediaId = dto.ThumbMediaId,
                    Title = dto.Title,
                    NeedOpenComment = dto.NeedOpenComment,
                    OnlyFansCanComment = dto.OnlyFansCanComment
                });
            }
            dynamic result = JsonConvert.DeserializeObject<dynamic>(this.weChatNewsMaterialService.AddPermanentNews(new NewsMaterialDto()
            {
                Articles = articles
            }));
            string mediaId = result.media_id;
            string response = WeChatHttpResponseHandle.ProcessMessage(new MaterialService().GetMaterial(mediaId, true, false));
            dynamic newsInfo = JsonConvert.DeserializeObject<dynamic>(response);
            int index = 0;
            foreach (WeChatNewsMaterialArticleRecordEntity entity in entities)
            {
                foreach (dynamic item in newsInfo.news_item.ToObject<List<dynamic>>())
                {
                    if (item.thumb_media_id == entity.ThumbMediaId)
                    {
                        entity.ThumbUrl = item.thumb_url;
                        WeChatMediaRecordEntity weChatMediaRecordEntity = this.weChatMediaRecordData.GetEntity(entity.ThumbMediaId);
                        entity.ImageUrl = weChatMediaRecordEntity.LocalUrl;
                    }
                }
                entity.MediaId = mediaId;
                entity.Index = index;
                index++;
                this.weChatNewsMaterialArticleRecordData.Add(entity);
            }
            WeChatMediaRecordEntity mediaEntity = new WeChatMediaRecordEntity()
            {
                MediaId = mediaId,
                FileName = entities[0].Title,
                Title = entities[0].Title,
                Description = entities[0].Title,
                IsTemporary = false,
                Url = entities[0].ContentSourceUrl,
                Type = WeChatMediaType.News
            };
            if (!this.weChatMediaRecordData.Add(mediaEntity))
            {
                throw new ArgumentException("网络异常，请重试！");
            }
            return this.Get(mediaId);
        }

        public void Delete(string mediaId)
        {
            Task task = new Task(() =>
            {
                this.weChatNewsMaterialService.DeletePermanentNews(mediaId);
                this.weChatNewsMaterialArticleRecordData.Delete(mediaId);
                this.weChatMediaRecordData.Delete(mediaId);
            });
            task.Start();
        }

        public WeChatMediaRecordDto Get(string mediaId)
        {
            WeChatMediaRecordDto weChatMediaRecordDto = this.weChatMediaRecordData.GetEntity(mediaId).As<WeChatMediaRecordDto>();
            weChatMediaRecordDto.WeChatNewsMaterialArticleRecords = this.weChatNewsMaterialArticleRecordData.Get(mediaId).As<IEnumerable<WeChatNewsMaterialArticleRecordDto>>();
            return weChatMediaRecordDto;
        }

        public PageableList<WeChatMediaRecordDto> Get(string mediaId, string title, DateTime? start, DateTime? end, bool? ascending, int pageIndex = 1, int pageSize = 10)
        {
            int dataCount;
            string host = configuration["CurrentlyImageHost"];
            PageableList<WeChatMediaRecordDto> result = new PageableList<WeChatMediaRecordDto>();
            if (string.IsNullOrWhiteSpace(title))
            {
                IEnumerable<WeChatMediaRecordEntity> weChatMediaRecordEntities = this.weChatMediaRecordData.GetRecords(mediaId, title, start, end, "News", false, ascending, out dataCount, pageIndex, pageSize);
                IEnumerable<WeChatMediaRecordDto> weChatMediaRecordDtos = weChatMediaRecordEntities.As<IEnumerable<WeChatMediaRecordDto>>();
                Parallel.ForEach(weChatMediaRecordDtos, (item) =>
                {
                    IEnumerable<WeChatNewsMaterialArticleRecordEntity> articleRecordEntities = this.weChatNewsMaterialArticleRecordData.Get(item.MediaId);
                    foreach (WeChatNewsMaterialArticleRecordEntity entity in articleRecordEntities)
                    {
                        entity.ImageUrl = string.Concat(host, entity.ImageUrl);
                    }
                    item.WeChatNewsMaterialArticleRecords = articleRecordEntities.As<IEnumerable<WeChatNewsMaterialArticleRecordDto>>();
                });
                result.Items = weChatMediaRecordDtos;
                result.Count = dataCount;
                return result;
            }
            else
            {
                IEnumerable<WeChatNewsMaterialArticleRecordEntity> articleRecordEntities = this.weChatNewsMaterialArticleRecordData.Get(title, start, end, ascending, out dataCount, pageIndex, pageSize);
                Parallel.ForEach(articleRecordEntities, (item) =>
                {
                    item.ImageUrl = string.Concat(host, item.ImageUrl);
                });
                List<WeChatMediaRecordDto> weChatMediaRecordDtos = new List<WeChatMediaRecordDto>();
                foreach (string smediaId in articleRecordEntities.Select(p => p.MediaId).Distinct())
                {
                    WeChatMediaRecordEntity weChatMediaRecordEntity = this.weChatMediaRecordData.GetEntity(smediaId);
                    WeChatMediaRecordDto weChatMediaRecordDto = weChatMediaRecordEntity.As<WeChatMediaRecordDto>();
                    //weChatMediaRecordDto.WeChatNewsMaterialArticleRecords = articleRecordEntities.Where(p => p.MediaId == smediaId).OrderBy(p => p.Index).As<IEnumerable<WeChatNewsMaterialArticleRecordDto>>();
                    IEnumerable<WeChatNewsMaterialArticleRecordEntity> allArticleRecordEntities = this.weChatNewsMaterialArticleRecordData.Get(smediaId);
                    foreach (WeChatNewsMaterialArticleRecordEntity entity in allArticleRecordEntities)
                    {
                        entity.ImageUrl = string.Concat(host, entity.ImageUrl);
                    }
                    weChatMediaRecordDto.WeChatNewsMaterialArticleRecords = allArticleRecordEntities.As<IEnumerable<WeChatNewsMaterialArticleRecordDto>>();
                    weChatMediaRecordDtos.Add(weChatMediaRecordDto);
                }
                result.Items = weChatMediaRecordDtos;
                result.Count = dataCount;
                return result;
            }
        }

        public WeChatMediaRecordDto Update(string mediaId, IEnumerable<WeChatNewsMaterialArticleRecordPutDto> weChatNewsMaterialArticleRecordPutDtos)
        {
            List<NewsArticles> articles = new List<NewsArticles>();
            foreach (WeChatNewsMaterialArticleRecordPutDto dto in weChatNewsMaterialArticleRecordPutDtos)
            {
                articles.Add(new NewsArticles()
                {
                    Author = dto.Author,
                    Content = dto.WeChatContent,
                    ContentSourceUrl = dto.ContentSourceUrl,
                    Digest = dto.Digest,
                    ShowCoverPic = 1,
                    ThumbMediaId = dto.ThumbMediaId,
                    Title = dto.Title,
                    NeedOpenComment = dto.NeedOpenComment,
                    OnlyFansCanComment = dto.OnlyFansCanComment
                });
            }
            for (int i = 0; i < articles.Count; i++)
            {
                this.weChatNewsMaterialService.UpdatePermanentNewsMaterial(mediaId, i, articles[i]);
            }
            string response = WeChatHttpResponseHandle.ProcessMessage(new MaterialService().GetMaterial(mediaId, true, false));
            dynamic newsInfo = JsonConvert.DeserializeObject<dynamic>(response);
            dynamic newsItem = newsInfo.news_item;
            IEnumerable<WeChatNewsMaterialArticleRecordEntity> weChatNewsMaterialArticleRecordEntities = this.weChatNewsMaterialArticleRecordData.Get(mediaId);
            List<WeChatNewsMaterialArticleRecordEntity> Records = new List<WeChatNewsMaterialArticleRecordEntity>();
            foreach(WeChatNewsMaterialArticleRecordEntity entity in weChatNewsMaterialArticleRecordEntities)
            {
                if (!weChatNewsMaterialArticleRecordPutDtos.Any(p => p.WeChatNewsMaterialArticleRecordId.Equals(entity.WeChatNewsMaterialArticleRecordId))){
                    this.weChatNewsMaterialArticleRecordData.DeleteArticle(entity.WeChatNewsMaterialArticleRecordId);
                }
                else
                {
                    Records.Add(entity);
                }
            }
            for (int i = 0; i < (int)newsItem.Count; i++)
            {
                DateTime updateTime = DateTime.Now;
                string thumbMediaId = newsItem[i].thumb_media_id;
                string thumbUrl = newsItem[i].thumb_url;
                WeChatMediaRecordEntity weChatMediaRecordEntity = this.weChatMediaRecordData.GetEntity(thumbMediaId);
                WeChatNewsMaterialArticleRecordEntity articleEntity = Records.Single(p => p.Index == i);
                weChatNewsMaterialArticleRecordData.Update(new WeChatNewsMaterialArticleRecordEntity()
                {
                    WeChatNewsMaterialArticleRecordId = articleEntity.WeChatNewsMaterialArticleRecordId,
                    Title = newsItem[i].title,
                    ThumbMediaId = thumbMediaId,
                    ShowCoverPic = newsItem[i].show_cover_pic,
                    Author = newsItem[i].author,
                    Digest = newsItem[i].digest,
                    Content = weChatNewsMaterialArticleRecordPutDtos.Single(p=>p.WeChatNewsMaterialArticleRecordId== articleEntity.WeChatNewsMaterialArticleRecordId).Content,
                    ContentSourceUrl = newsItem[i].content_source_url,
                    MediaId = mediaId,
                    UpdateTime = updateTime,
                    NeedOpenComment = newsItem[i].need_open_comment,
                    OnlyFansCanComment = newsItem[i].only_fans_can_comment,
                    Index = i,
                    ThumbUrl = thumbUrl,
                    ImageUrl = weChatMediaRecordEntity.LocalUrl
                });
            }
            return this.Get(mediaId);
        }

        private string TransformMediaTagCode(string content)
        {
            string html = content;
            Regex regex = new Regex(RegexPatterns.HTML_TAG_SINGLE);
            while (regex.IsMatch(html))
            {
                Match match = regex.Match(html);
                if (match.Value.IndexOf("<img") > -1)
                {
                    string imgTag = match.Value;
                    Regex srcRegex = new Regex("\\s{1}src[\\s]?=[\\s]?\"([^\"]*.)?[\"]");
                    if (srcRegex.IsMatch(imgTag))
                    {
                        imgTag = srcRegex.Replace(imgTag, "");
                    }
                    srcRegex = new Regex("\\s{1}data-src[\\s]?=[\\s]?\"");
                    if (srcRegex.IsMatch(imgTag))
                    {
                        imgTag = srcRegex.Replace(imgTag, "src=\"");
                    }
                    html = regex.Replace(match.Value, imgTag);
                }
            }
            return html;

        }

        private string SaveImage(WeChatMediaType weChatMediaType, string name, string url)
        {
            string path = string.Format("{0}/{1}", weChatMediaType.ToString().ToLower(), DateTime.Now.ToString("yyyy-MM-dd"));
            string parentDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).FullName;
            string saveDirectory = Path.Combine(parentDirectory, configuration["WebsiteName"]);
            path = Path.Combine(saveDirectory, path);
            using (WebClient webClient = new WebClient())
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                path = Path.Combine(path, name);
                if (!File.Exists(path))
                {
                    webClient.DownloadFile(url, path);
                }
            }
            return path.Replace(saveDirectory, "");
        }
    }
}
